package utils

import (
	"errors"
	"fmt"
	"regexp"
	"strconv"
	"time"
)

const TimeFormat = "2006-01-02 15:04:05"

var TimeTemplates = []string{
	"2006-01-02 15:04:05", //常规类型
	"2006-01-02",
	"2006-01",
	"15:04:05",
}

func NowUnix() int64 {
	currentTime := time.Now()
	return time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), currentTime.Hour(), currentTime.Minute(), currentTime.Second(), 0, currentTime.Location()).Unix()
}

func NowDateTime() time.Time {
	currentTime := time.Now()
	return time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 0, 0, 0, 0, currentTime.Location())
}

func TimeFormate(t time.Time, index int) string {
	if index < 0 || index > len(TimeTemplates) {
		index = 0
	}
	return t.Format(TimeTemplates[index])
}

func NowDateFormat(now int64, index int) string {
	var tm time.Time
	if now == 0 {
		tm = time.Now()
	} else {
		tm = time.Unix(now, 0)
	}
	return TimeFormate(tm, index)
}

func StringToUnix(t string) int64 {
	n := time.Now()
	if t != "" {
		n, _ = time.Parse(TimeTemplates[0], t)
	}
	return time.Date(n.Year(), n.Month(), n.Day(), n.Hour(), n.Minute(), n.Second(), 0, n.Location()).Unix()
}

func ZeroTimeUnix(t string) int64 {
	n := time.Now()
	if t != "" {
		n, _ = time.Parse(TimeTemplates[0], t)
	}
	return time.Date(n.Year(), n.Month(), n.Day(), 0, 0, 0, 0, n.Location()).Unix()
}

func ChangeFormatDate(dateStr string, inpIndex, outIndex int) string {
	parsedTime, _ := time.Parse(TimeTemplates[inpIndex], dateStr)
	return TimeFormate(parsedTime, outIndex)
}

func ForeDate(dt string) time.Time {
	nTime := time.Now()
	if dt != "" {
		return nTime
	}
	return nTime.AddDate(0, 0, -1)
}

// 获取某一天的0点时间
func TimeZeroTime(d time.Time) time.Time {
	return time.Date(d.Year(), d.Month(), d.Day(), 0, 0, 0, 0, d.Location())
}

// 获取传入的时间所在月份的第一天，即某月第一天的0点。如传入time.Now(), 返回当前月份的第一天0点时间。
func FirstDateOfMonth(d time.Time) time.Time {
	d = d.AddDate(0, 0, -d.Day()+1)
	return TimeZeroTime(d)
}

// 获取传入的时间所在月份的最后一天，即某月最后一天的0点。如传入time.Now(), 返回当前月份的最后一天0点时间。
func LastDateOfMonth(d time.Time) time.Time {
	return TimeZeroTime(d).AddDate(0, 1, -1)
}

func StringToTime(str string, index int) time.Time {
	t, err := time.ParseInLocation(TimeTemplates[index], str, time.Local)
	if nil == err && !t.IsZero() {
		return t
	}
	return time.Time{}
}

func TimeToString(t time.Time, index int) string {
	if t.IsZero() {
		return ""
	}
	return t.Format(TimeTemplates[index])
}

// GenerateMonthsInRange 生成指定范围内的所有月份
func GenerateMonthsInRange(startDate, endDate string) ([]string, error) {
	start, err := ParseSimplifiedDate(startDate)
	if err != nil {
		return nil, err
	}
	end, err := ParseSimplifiedDate(endDate)
	if err != nil {
		return nil, err
	}

	var months []string

	for curr := start; !curr.After(end); curr = curr.AddDate(0, 1, 0) {
		months = append(months, curr.Format("2006-01"))
	}

	return months, nil
}

// parseSimplifiedDate 解析简化的日期格式，例如 "2024-1" 成为标准的 "2024-01" 格式
func ParseSimplifiedDate(dateStr string) (time.Time, error) {
	re := regexp.MustCompile(`(\d{4})-(\d{1,2})`)
	matches := re.FindStringSubmatch(dateStr)
	if len(matches) != 3 {
		return time.Time{}, errors.New("invalid date format")
	}

	year, _ := strconv.Atoi(matches[1])
	month, _ := strconv.Atoi(matches[2])

	return time.Parse("2006-01", fmt.Sprintf("%d-%02d", year, month))
}

func IntToDateYm(year int, month int) (time.Time, error) {
	return time.Parse("2006-01", fmt.Sprintf("%d-%02d", year, month))
}

func AddDays(dateStr string, days int) (string, error) {
	// 定义日期解析格式，必须是固定的格式"2006-01-02"。
	// 解析输入的日期字符串。
	date, err := time.Parse(TimeTemplates[1], dateStr)
	if err != nil {
		return "", err // 如果解析失败，返回错误。
	}
	// 计算新日期，使用Date.AddDate(years, months, days)，注意days可以直接为负数。
	newDate := date.AddDate(0, 0, days)

	// 返回新的日期字符串。
	return newDate.Format(TimeTemplates[1]), nil
}

func IsWithinTimeRange(startHour, endHour int) bool {
	// 获取当前时间
	now := time.Now()

	// 获取当前的小时和分钟
	currentHour := now.Hour()
	currentMinute := now.Minute()

	// 判断当前时间是否在 07:00 ~ 22:00 范围内
	if currentHour > startHour && currentHour < endHour {
		return true
	} else if currentHour == startHour && currentMinute >= 0 {
		return true
	} else if currentHour == endHour && currentMinute == 0 {
		return true
	} else {
		return false
	}
}

func GetMonthsAgo(month int) string {
	// 获取当前时间
	now := time.Now()
	// 计算指定月份前的时间
	now = now.AddDate(0, -month, 0)
	return now.Format(TimeFormat)
}
